package com.expdatacloud.dto;

import java.io.Serializable;

/**
 * @author jie
 * @date 2019/11/12 -11:51
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ApiResponse<T> implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = -7467991410407090791L;
    protected int code;
    protected long count;
    protected String msg;
    protected T data;

    /**
     * Status code (200) indicating the request succeeded normally.
     */
    public static final int SC_OK = 0;

    /**
     * Status code (400) indicating the request sent by the client was
     * syntactically incorrect.
     */

    public static final int SC_BAD_REQUEST = 400;

    /**
     * Status code (403) indicating the server understood the request but
     * refused to fulfill it.
     */

    public static final int SC_FORBIDDEN = 403;

    /**
     * Status code (500) indicating an error inside the HTTP server which
     * prevented it from fulfilling the request.
     */

    public static final int SC_INTERNAL_SERVER_ERROR = 500;

    /**
     * Singleton instance the success is true,status is SC_OK.
     * <p>
     * please do not modify this instance properties.
     *
     * @see #ok()
     */

    public static final ApiResponse OK = ok();

    /**
     * Singleton instance the success is false,status is
     * SC_INTERNAL_SERVER_ERROR.
     * <p>
     * please do not modify this instance properties.
     */

    public static final ApiResponse ERROR = fail(SC_INTERNAL_SERVER_ERROR);

    /**
     * Singleton instance the success is false,status is SC_FORBIDDEN.
     * <p>
     * please do not modify this instance properties.
     */
    public static final ApiResponse FORBIDDEN = fail(SC_FORBIDDEN);

    /**
     * Singleton instance the success is false,status is SC_BAD_REQUEST.
     * <p>
     * please do not modify this instance properties.
     */
    public static final ApiResponse FAIL = fail(SC_BAD_REQUEST);

    public static final ApiResponse NULL = fail(SC_OK);

    public ApiResponse(int code, String msg, T content) {
        this.code = code;
        this.msg = msg;
        this.data = content;

    }

    public ApiResponse() {

    }

    public ApiResponse(int code) {
        this(code, null, null);
    }

    public static final <T> ApiResponse of(int code, String msg) {
        return new ApiResponse(code, msg, null);
    }

    public static final <T> ApiResponse of(int code, String msg, T record) {
        return new ApiResponse(code, msg, record);
    }

    public static final <T> ApiResponse of(int code) {
        return new ApiResponse(code);
    }

    /**
     * create instance the success is true,status is SC_OK(200)
     *
     * @see #SC_OK
     **/
    private static final ApiResponse ok() {
        return of(SC_OK);
    }

    /**
     * create instance the success is true,status is SC_OK(200)
     *
     * @param records
     * @see #SC_OK
     **/
    public static final <T> ApiResponse ok(T records) {
        ApiResponse apiResponse = ok();

        if (records != null) {
            apiResponse.data = records;
        }
        return apiResponse;
    }

    public static final <T> ApiResponse ok(long count,T records) {
        ApiResponse apiResponse = ok();
        apiResponse.count = count;
        if (records != null) {
            apiResponse.data = records;
        }
        return apiResponse;
    }
    /**
     * create instance the success is false,status is
     * SC_INTERNAL_SERVER_ERROR(500)
     *
     * @see #SC_INTERNAL_SERVER_ERROR
     **/
    public static final ApiResponse error(String value) {
        return fail(SC_INTERNAL_SERVER_ERROR).msg(value);
    }

    public static final ApiResponse error(int code, String value) {
        return fail(code).msg(value);
    }

    /**
     * create instance the success is false,status is SC_BAD_REQUEST(400) add a
     * message,Key can not be null
     *
     * @param value
     * @see #SC_BAD_REQUEST
     **/
    public static final ApiResponse fail(String value) {
        return fail(SC_BAD_REQUEST).msg(value);
    }

    /**
     * create instance the success is false,status is SC_FORBIDDEN(403)
     *
     * @param value
     * @see #SC_BAD_REQUEST
     **/
    public static final ApiResponse forbidden(String value) {
        return fail(SC_FORBIDDEN).msg(value);
    }

    public static final ApiResponse forbidden() {
        return fail(SC_FORBIDDEN);
    }

    /**
     * create instance the success is false
     *
     * @param status
     * @see #of
     **/
    private static final ApiResponse fail(int status) {
        return of(status);
    }

    /**
     * add a message,Key can not be null
     *
     * @param value
     **/
    public ApiResponse msg(String value) {
        this.msg = value;
        return this;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setData(T data) {
        this.data = data;
    }

    public long getCount() {
        return count;
    }

    public void setCount(long count) {
        this.count = count;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("ApiResponse{");
        sb.append("data=").append(data);
        sb.append(", code=").append(code);
        sb.append(", msg='").append(msg).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
